<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<!--
1. [].slice.call(lis): 将伪数组转换为真数组
2. node.nodeType: 得到节点类型
3. Object.defineProperty(obj, propertyName, {}): 给对象添加属性(指定描述符)
4. Object.keys(obj): 得到对象自身可枚举属性组成的数组
5. obj.hasOwnProperty(prop): 判断prop是否是obj自身的属性
6. DocumentFragment: 文档碎片(高效批量更新多个节点)
-->
<body>
<div id="test">尚硅谷IT教育</div>

<ul id="fragment_test">
    <li>test1</li>
    <li>test2</li>
    <li>test3</li>
</ul>
<script type="text/javascript">
    const lis = document.getElementsByTagName('li');
    console.log(lis instanceof Object,lis instanceof Array); // true false
    var call = [].slice.call(lis);
    console.log(call instanceof Array); // true
    Array.prototype.slice2 = function (start, end) {
        start = start || 0
        end = end || this.length
        const arr = []
        for (var i = start; i < end; i++) {
            arr.push(this[i])
        }
        return arr
    }
    var zz = [1,2,3,4,5,6].slice2(1,2);
    console.log(zz);
    //2. node.nodeType: 得到节点类型
    const elementNode = document.getElementById('test')
    const attrNode = elementNode.getAttributeNode('id')
    const textNode = elementNode.firstChild
    console.log(elementNode.nodeType, attrNode.nodeType, textNode.nodeType) //1 2 3

    //3. Object.defineProperty(obj, propertyName, {}): 给对象添加属性(指定描述符)
    const obj = {
        firstName: 'A',
        lastName: 'B'
    }
    Object.defineProperty(obj,'fullName',{
        get() {
            return this.firstName + "-" + this.lastName;
        },
        set(vale)
        {
            const names = vale.split("-");
            this.firstName = names[0]
            this.lastName = names[1]
        },
        enumerable: true
    });
    console.log(obj.fullName) //A-B
    obj.fullName = 'C-D';
    console.log(obj.firstName,obj.lastName) //C D
    Object.defineProperty(obj, 'fullName2', {
        configurable: false, //是否可以重新define
        enumerable: false, // 是否可以枚举(for..in / keys())
        value: 'A-B', // 指定初始值
        writable: false // value是否可以修改
    })
    console.log(obj.fullName2)  // A-B
    obj.fullName2 = 'E-F'
    console.log(obj.fullName2) // A-B

    // 得到对象自身可枚举属性组成的数组
    const names = Object.keys(obj)
    console.log(names)

    //5. obj.hasOwnProperty(prop): 判断prop是否是obj自身的属性
    console.log(obj.hasOwnProperty('fullName'), obj.hasOwnProperty('fullName2'))  // true true
    console.log(obj.hasOwnProperty('toString')) // false

    //6. DocumentFragment: 文档碎片(高效批量更新多个节点)
    // document: 对应显示的页面, 包含n个elment  一旦更新document内部的某个元素界面更新
    // documentFragment: 内存中保存n个element的容器对象(不与界面关联), 如果更新framgnet中的某个element, 界面不变
    /*
    <ul id="fragment_test">
      <li>test1</li>
      <li>test2</li>
      <li>test3</li>
    </ul>
     */
    const ul = document.getElementById('fragment_test')
    // 1. 创建fragment
    const fragment = document.createDocumentFragment()
    // 2. 取出ul中所有子节点取出保存到fragment
    let child
    while(child=ul.firstChild) { // 一个节点只能有一个父亲,所以 fragment.appendChild(child)会移除节点
        fragment.appendChild(child)  // 先将child从ul中移除, 添加为fragment子节点
    }

    // 3. 更新fragment中所有li的文本
    Array.prototype.slice.call(fragment.childNodes).forEach(node => {
        if (node.nodeType===1) { // 元素节点 <li>
            node.textContent = 'atguigu'
        }
    })

    // 4. 将fragment插入ul
    ul.appendChild(fragment)
</script>

</body>
</html>
